package com.baijiayun.liveuibase.widgets.courseware;

import android.text.TextUtils;

import androidx.annotation.CallSuper;
import androidx.annotation.NonNull;

import android.text.TextUtils;

import com.baijiahulian.common.networkv2.BJDownloadCallback;
import com.baijiahulian.common.networkv2.BJProgressCallback;
import com.baijiahulian.common.networkv2.BJResponse;
import com.baijiahulian.common.networkv2.HttpException;
import com.baijiayun.livecore.context.LPConstants;
import com.baijiayun.livecore.context.LiveRoom;
import com.baijiayun.livecore.models.LPDocumentModel;
import com.baijiayun.livecore.models.LPShortResult;
import com.baijiayun.livecore.models.LPUploadDocModel;
import com.baijiayun.livecore.models.LPUploadHomeworkUserModel;
import com.baijiayun.livecore.models.LPUploadingDocumentModel;
import com.baijiayun.livecore.models.file.IFileModel;
import com.baijiayun.livecore.models.file.cloudfile.LPCloudFileModel;
import com.baijiayun.livecore.models.file.homework.LPHomeworkModel;
import com.baijiayun.livecore.models.file.homework.LPUploadHomeworkModel;
import com.baijiayun.livecore.models.imodels.IUserModel;
import com.baijiayun.livecore.models.roomresponse.LPAllowUploadHomeworkModel;
import com.baijiayun.livecore.utils.LPJsonUtils;
import com.baijiayun.livecore.utils.LPLogger;
import com.baijiayun.livecore.utils.LPRxUtils;
import com.baijiayun.livecore.viewmodels.impl.LPDocListViewModel;
import com.baijiayun.liveuibase.utils.BaseUIUtils;
import com.baijiayun.liveuibase.widgets.courseware.models.UploadDocModel;
import com.google.gson.JsonObject;

import org.jetbrains.annotations.NotNull;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
import okhttp3.ResponseBody;

public abstract class CourseManagePresenter implements BaseCourseWareContract.BaseCourseWarePresenter {
    private final String TAG = CourseManagePresenter.class.getSimpleName();

    private BaseCourseWareContract.BaseCourseWareView view;
    private HomeworkSaveUtil mHomeworkSaveHandler;

    private LiveRoom liveRoom;
    private CompositeDisposable compositeDisposable = new CompositeDisposable();

    private LinkedBlockingQueue<LPUploadingDocumentModel> uploadingDocumentQueue;
    private LinkedBlockingQueue<LPUploadingDocumentModel> uploadingImageQueue;
    private Map<String, Disposable> disposablesOfUploading;
    private Map<String, Disposable> disposablesOfRequestProgress;
    private Disposable disposableOfReqImg;

    public CourseManagePresenter(BaseCourseWareContract.BaseCourseWareView view) {
        this.view = view;
        mHomeworkSaveHandler = new HomeworkSaveUtil();
        uploadingDocumentQueue = new LinkedBlockingQueue<>();
        uploadingImageQueue = new LinkedBlockingQueue<>();
        disposablesOfUploading = new HashMap<>();
        disposablesOfRequestProgress = new HashMap<>();
    }

    // region 作业相关
    @Override
    public void sendHomeWork(String path, boolean isImg) {
        // 上传文件
        LPUploadingDocumentModel model = new LPUploadingDocumentModel(path);
        model.setImg(isImg);
        model.setHomework(true);
        uploadingDocumentQueue.offer(model);
        continueUploadQueue();
    }

    @Override
    public void deleteHomework(String homeworkId, LPUploadHomeworkUserModel userModel) {
        liveRoom.getDocListVM().deleteHomework(homeworkId, userModel, this);
    }

    @Override
    public void downloadHomework(LPHomeworkModel homeworkModel, File homeworkFile) {
        liveRoom.getDocListVM().downLoadHomework(homeworkModel.getHomeworkId(), homeworkFile, new BJDownloadCallback() {
            @Override
            public void onDownloadFinish(BJResponse bjResponse, File file) {
                if (view == null) {
                    return;
                }
                // 通知 view
                // 更改文件名，添加后缀
                boolean rst = file.renameTo(new File(file.getPath() + homeworkModel.getFext()));
                if (rst) {
                    view.onDownloadSuccess(homeworkModel.getHomeworkId());
                    mHomeworkSaveHandler.saveHomework(
                            new HomeworkSaveUtil.SaveMessageModel(liveRoom.getRoomTitle(), liveRoom.getRoomId(), homeworkModel));
                } else {
                    view.onDownloadFailed(homeworkModel.getHomeworkId(), "文件异常，下载失败");
                }
            }

            @Override
            public void onProgress(long l, long l1) {
                if (view == null) {
                    return;
                }
                view.onDownloadProgress(homeworkModel.getHomeworkId(), (float) l / l1);
            }

            @Override
            public void onFailure(HttpException e) {
                if (view == null) {
                    return;
                }
                view.onDownloadFailed(homeworkModel.getHomeworkId(), e.getMessage());
            }
        });
    }

    @Override
    public void requestSearchHomework(String keyword) {
        liveRoom.getDocListVM().requestHomeworkAllList(keyword);
    }

    private void uploadHomework(LPUploadingDocumentModel model) {
        IUserModel currentUser = liveRoom.getCurrentUser();
        liveRoom.getDocListVM().uploadHomeworkWithProgress(model.getFilePath()
                , new LPUploadHomeworkUserModel(currentUser.getNumber()
                        , currentUser.getName(), currentUser.getType()), new CourseManageUploadCallback(model) {
                    @Override
                    public void onResponse(BJResponse response) {
                        super.onResponse(response);
                        if (shortResult == null) {
                            return;
                        }
                        // 上传成功
                        try {
                            LPUploadHomeworkModel uploadHomeworkModel =
                                    LPJsonUtils.parseJsonObject((JsonObject) shortResult.data, LPUploadHomeworkModel.class);
                            uploadHomeworkModel.setUploadSource(LPConstants.BINDER_SOURCE_LOCAL);

                            if (!uploadHomeworkModel.isCanPreview() || model.isImg()) {
                                // 如果不能预览 or 是图片文件，那么不需要转码，发送 homework add 即可
                                LPRxUtils.dispose(disposablesOfUploading.remove(uploadHomeworkModel.getFileId()));
                                LPRxUtils.dispose(disposablesOfRequestProgress.remove(uploadHomeworkModel.getFileId()));
                                view.removeUploadDocument(model.getFilePath());
                                // homework add
                                liveRoom.getDocListVM().addHomework(LPHomeworkModel.copyValueFromUploadModel(uploadHomeworkModel));
                                return;
                            }
                            model.setHomeworkId(uploadHomeworkModel.getHomeworkId());
                            model.setFileId(uploadHomeworkModel.getFileId());
                            view.startTranslate(model);
                            Disposable disposableOfInterval = Observable.interval(2, TimeUnit.SECONDS)
                                    .subscribe(aLong -> checkTranslate(uploadHomeworkModel, model));
                            disposablesOfUploading.put(uploadHomeworkModel.getFileId(), disposableOfInterval);
                        } catch (Exception e) {
                            LPLogger.d(TAG, e.getMessage());
                        }
                        continueUploadQueue();
                    }
                }
        );
    }

    private void checkTranslate(@NotNull LPUploadHomeworkModel uploadHomeworkModel, LPUploadingDocumentModel model) {
        if (!disposablesOfUploading.containsKey(uploadHomeworkModel.getFileId())) {
            // 如果已经不包含此 id，返回
            return;
        }
        // 如果可以预览，则需要先转码，转码完成后 先 homework add，然后 doc add
        Disposable disposableOfProgress = liveRoom.getDocListVM().requestTransferProgress(uploadHomeworkModel.getFileId())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(progressModel -> {
                    if (progressModel.progress < 0) {
                        view.translateFailure(model, progressModel);
                        LPRxUtils.dispose(disposablesOfUploading.remove(uploadHomeworkModel.getFileId()));
                        LPRxUtils.dispose(disposablesOfRequestProgress.remove(uploadHomeworkModel.getFileId()));
                        return;
                    }
                    if (progressModel.progress >= 100) {
                        view.removeUploadDocument(model.getFilePath());
                        LPRxUtils.dispose(disposablesOfUploading.remove(uploadHomeworkModel.getFileId()));
                        LPRxUtils.dispose(disposablesOfRequestProgress.remove(uploadHomeworkModel.getFileId()));

                        // homework add
                        liveRoom.getDocListVM().addHomework(LPHomeworkModel.copyValueFromUploadModel(uploadHomeworkModel));
                    }
                });
        disposablesOfRequestProgress.put(uploadHomeworkModel.getFileId(), disposableOfProgress);
    }

    @Override
    public void requestHomeworkSupport() {
        liveRoom.getDocListVM().requestHomeworkSupport();
    }

    @Override
    public void cancelDownloadHomework(File file) {
        liveRoom.getDocListVM().cancelDownloadHomework(file);
    }
    // endregion

    // region ppt相关

    @Override
    public void sendPPTDocument(@NonNull String path, boolean isAnimPPT) {
        LPUploadingDocumentModel model = new LPUploadingDocumentModel(path);
        model.setAnimPPT(isAnimPPT);
        uploadingDocumentQueue.offer(model);
        continueUploadQueue();
    }

    private void uploadDoc(LPUploadingDocumentModel model) {
        liveRoom.getDocListVM().uploadPPTWithProgress(model.getFilePath(), model.isAnimPPT(), this, new CourseManageUploadCallback(model) {
            @Override
            public void onResponse(BJResponse response) {
                super.onResponse(response);
                if (shortResult == null) {
                    return;
                }
                try {
                    LPUploadDocModel lpUploadDocModel = LPJsonUtils.parseJsonObject((JsonObject) shortResult.data, LPUploadDocModel.class);
                    String fid = String.valueOf(lpUploadDocModel.fileId);
                    model.setFileId(fid);
                    view.startTranslate(model);
                    Disposable disposableOfInterval = Observable.interval(2, TimeUnit.SECONDS)// 每2s轮询
                            .subscribe(aLong -> {
                                Disposable disposableOfProgress = liveRoom.getDocListVM().requestTransferProgress(fid)
                                        .observeOn(AndroidSchedulers.mainThread())
                                        .subscribe(progressModel -> {
                                            if (progressModel.progress < 0) {
                                                view.translateFailure(model, progressModel);
                                                LPRxUtils.dispose(disposablesOfUploading.remove(progressModel.fid));
                                                LPRxUtils.dispose(disposablesOfRequestProgress.remove(progressModel.fid));
                                                return;
                                            }
                                            view.translateProgress(model.getFilePath(), progressModel.progress);
                                            if (progressModel.progress >= 100) {
                                                view.removeUploadDocument(model.getFilePath());
                                                LPRxUtils.dispose(disposablesOfUploading.remove(progressModel.fid));
                                                LPRxUtils.dispose(disposablesOfRequestProgress.remove(progressModel.fid));
                                                liveRoom.getDocListVM().addDocument(lpUploadDocModel);
                                            }
                                        });
                                disposablesOfRequestProgress.put(fid, disposableOfProgress);
                            });
                    disposablesOfUploading.put(fid, disposableOfInterval);
                } catch (Exception e) {
                    LPLogger.d(TAG, e.getMessage());
                }
                continueUploadQueue();
            }
        });
    }
    // endregion

    // region 通用逻辑
    private void continueUploadQueue() {
        LPUploadingDocumentModel model = uploadingDocumentQueue.poll();
        if (model == null) {
            return;
        }
        // 增加上传 item
        if (view.addUploadModel(model)) {
            // 上传合法，add upload 成功，开始上传
            if (model.isHomework()) {
                uploadHomework(model);
            } else if (model.isCloudFile()) {
                uploadCloudFile(model);
            } else {
                uploadDoc(model);
            }
        }
    }

    // 取消上传中的进程
    @Override
    public void cancelUpload(String path) {
        liveRoom.getDocListVM().cancelUpload(new File(path));
        view.removeUploadDocument(path);
    }

    /**
     * 取消转码中的进程
     * @param model 上传model
     */
    @Override
    public void deleteTranslating(UploadDocModel model) {
        if (TextUtils.isEmpty(model.getFileId())) {
            // fileId 为空，则直接移除视图
            view.removeUploadDocument(model.getFileId());
            return;
        }
        LPRxUtils.dispose(disposablesOfUploading.remove(model.getFileId()));
        LPRxUtils.dispose(disposablesOfRequestProgress.remove(model.getFileId()));
        if (model.isCloudFile()) {
            liveRoom.getCloudFileVM().deleteCloudFile(model.getFileId());
        } else if (model.isHomeWork()) {
            liveRoom.getDocListVM().deleteHomework(model.getHomeworkId(),
                    LPUploadHomeworkUserModel.copyData(liveRoom.getCurrentUser()), this);
        } else {
            liveRoom.getDocListVM().deleteDocument(model.getFileId());
        }
        view.removeUploadDocument(model.getPath());
    }
    // endregion

    // region 云盘相关
    @Override
    public void sendPPTCloudFile(String path, boolean isAnimPPT, boolean isImg) {
        LPUploadingDocumentModel model = new LPUploadingDocumentModel(path, liveRoom.getCurrentUser());
        model.setCloudFile(true);
        model.setAnimPPT(isAnimPPT);
        model.setImg(isImg);
        uploadingDocumentQueue.offer(model);
        continueUploadQueue();
    }

    private void uploadCloudFile(LPUploadingDocumentModel model) {
        liveRoom.getCloudFileVM().uploadCloudFileWithProgress(model, new CourseManageUploadCallback(model) {
            @Override
            public void onResponse(BJResponse response) {
                super.onResponse(response);
                if (shortResult == null) {
                    return;
                }
                // 上传成功
                try {
                    LPCloudFileModel cloudFileModel = LPJsonUtils.parseJsonObject((JsonObject) shortResult.data, LPCloudFileModel.class);
                    model.setFileId(cloudFileModel.getFileId());
                    view.startTranslate(model);
                    Disposable disposableOfInterval = Observable.interval(2, TimeUnit.SECONDS)
                            .subscribe(aLong -> checkTranslate(cloudFileModel, model));
                    disposablesOfUploading.put(cloudFileModel.getFileId(), disposableOfInterval);
                } catch (Exception e) {
                    LPLogger.d(TAG, e.getMessage());
                }
                continueUploadQueue();
            }
        });
    }

    @Override
    public void requestCloudFileInDir(LPCloudFileModel dirFileModel) {
        if (dirFileModel == null || !dirFileModel.isDirectory()) {
            LPLogger.d(TAG, "requestCloudFileInDir, dir is null or is not directory");
            return;
        }
        liveRoom.getCloudFileVM().requestCloudFileInDir(dirFileModel);
    }

    private void checkTranslate(@NotNull LPCloudFileModel cloudFileModel, LPUploadingDocumentModel model) {
        if (!disposablesOfUploading.containsKey(cloudFileModel.getFileId())) {
            return;
        }
        if (model.isImg()) {
            // 是图片文件，则不需要转码过程，显示为上传成功
            view.removeUploadDocument(model.getFilePath());
            liveRoom.getCloudFileVM().addCloudFile(cloudFileModel);
            LPRxUtils.dispose(disposablesOfUploading.remove(cloudFileModel.getFileId()));
            return;
        }
        Disposable disposableOfTransfer = liveRoom.getDocListVM().requestTransferProgress(
                cloudFileModel.getFileId())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(progressModel -> {
                    if (progressModel.progress < 0) {
                        view.translateFailure(model, progressModel);
                        LPRxUtils.dispose(disposablesOfUploading.remove(cloudFileModel.getFileId()));
                        LPRxUtils.dispose(disposablesOfRequestProgress.remove(cloudFileModel.getFileId()));
                        return;
                    }
                    if (progressModel.progress >= 100) {
                        view.removeUploadDocument(model.getFilePath());

                        LPRxUtils.dispose(disposablesOfUploading.remove(cloudFileModel.getFileId()));
                        LPRxUtils.dispose(disposablesOfRequestProgress.remove(cloudFileModel.getFileId()));

                        // 添加云盘文件
                        liveRoom.getCloudFileVM().addCloudFile(cloudFileModel);
                    }
                });
        disposablesOfRequestProgress.put(cloudFileModel.getFileId(), disposableOfTransfer);
    }

    /**
     * 在点击"同步并播放"按钮时调用以获取之前的文档信息并 执行 doc_add_trigger
     */
    @Override
    public void requestFileTransfer(IFileModel fileModel, BaseCourseWareContract.IOnRequestTransferListener listener) {
        if (listener == null || liveRoom == null) {
            return;
        }
        String fileId = fileModel.getFileId();
        String fExt = fileModel.getFExt();
        long size = fileModel.getSize();
        String userName = fileModel.getUserName();
        if (TextUtils.isEmpty(fileId)) {
            return;
        }
        // 检查 doc 是否已 add
        List<LPDocListViewModel.DocModel> docModels = liveRoom.getDocListVM().getDocList();
        for (LPDocListViewModel.DocModel docModel : docModels) {
            if (docModel.docId.equals(fileModel.getFileId())) {
                listener.onSuccess(docModel);
                return;
            }
        }
        listener.onWaitForDocAdd();
        if (BaseUIUtils.isImageFile(fExt)) {
            // 如果是图片，请求获取图片参数，并 doc add 到教室文件
            LPRxUtils.dispose(disposableOfReqImg);
            disposableOfReqImg = liveRoom.getDocListVM().getObservableOfDocumentImages(fileId)
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(imgModel -> {
                        LPDocumentModel model;
                        if (fileModel instanceof LPCloudFileModel) {
                            model = LPDocumentModel.getImgModelWithUserInfo(
                                    fileId, fExt, imgModel.name,
                                    imgModel.width, imgModel.height, imgModel.url,
                                    userName,null,null)
                                    .buildCloudFile(true);
                        } else if (fileModel instanceof LPUploadHomeworkModel) {
                            model = LPDocumentModel.getImgModelWithUserInfo(
                                    fileId, fExt, imgModel.name,
                                    imgModel.width, imgModel.height, imgModel.url,
                                    userName,null,null)
                                    .buildHomework(true, ((LPUploadHomeworkModel) fileModel).getHomeworkId());
                        } else {
                            return;
                        }
                        model.size = size;
                        model.bindSource = LPConstants.BINDER_SOURCE_LOCAL;
                        liveRoom.getDocListVM().addPictureDocument(model);
                        LPRxUtils.dispose(disposableOfReqImg);
                    });
            // 通知视图等待 doc add
            return;
        }
        // 未找到，即未曾 doc add，则doc add

        if (fileModel instanceof LPCloudFileModel) {
            liveRoom.getDocListVM().addCloudFile((LPCloudFileModel) fileModel);
        } else if (fileModel instanceof LPUploadHomeworkModel) {
            liveRoom.getDocListVM().addDocument((LPUploadHomeworkModel) fileModel);
        }
    }

    // endregion

    // region 图片上传
    @Override
    public void sendImageShape(String path, boolean isCloudFile) {
        LPUploadingDocumentModel model = new LPUploadingDocumentModel(path);
        model.setCloudFile(isCloudFile);
        uploadingImageQueue.offer(model);
        continueUploadImageQueue();
    }

    @Override
    public void sendChatImageShape(String path) {
        LPUploadingDocumentModel model = new LPUploadingDocumentModel(path);
        model.setFromChat(true);
        uploadingImageQueue.offer(model);
        continueUploadImageQueue();
    }

    private void continueUploadImageQueue() {
        LPUploadingDocumentModel model = uploadingImageQueue.poll();
        if (model == null || view == null) {
            return;
        }
        view.addUploadModel(model);
        liveRoom.getDocListVM().uploadImageWithProgress(model.getFilePath(), this, new CourseManageUploadCallback(model) {
            @Override
            public void onFailure(HttpException e) {
                super.onFailure(e);
                if (model.isFromChat()) {
                    BaseUIUtils.deleteFile(model.getFilePath());
                }
            }

            @Override
            public void onResponse(BJResponse bjResponse) {
                super.onResponse(bjResponse);
                try {
                    if (shortResult == null || view == null) {
                        return;
                    }
                    LPUploadDocModel lpUploadDocModel = LPJsonUtils.parseJsonObject((JsonObject) shortResult.data, LPUploadDocModel.class);
                    IUserModel currentUser = liveRoom.getCurrentUser();
                    LPDocumentModel documentModel = LPDocumentModel.getImgModelWithUserInfo(
                            String.valueOf(lpUploadDocModel.fileId), lpUploadDocModel.fext, lpUploadDocModel.name
                            , lpUploadDocModel.width, lpUploadDocModel.height, lpUploadDocModel.url
                            , currentUser.getName(),currentUser.getNumber(),currentUser.getType());
                    documentModel.size = lpUploadDocModel.size;
                    view.removeUploadDocument(model.getFilePath());
                    if (liveRoom.getDocListVM().addPictureDocument(documentModel) == null && model.isFromChat()) {
                        //上传成功后删除本地文件
                        BaseUIUtils.deleteFile(model.getFilePath());
                    }
                } catch (Exception e) {
                    LPLogger.d(TAG, e.getMessage());
                }
                continueUploadImageQueue();
            }
        });
    }
    // endregion

    public void subscribe(LiveRoom liveRoom) {
        this.liveRoom = liveRoom;
        uploadingDocumentQueue.clear();
        uploadingImageQueue.clear();
        disposablesOfUploading.clear();
        disposablesOfRequestProgress.clear();
        if (liveRoom == null) {
            return;
        }

        compositeDisposable.add(liveRoom.getDocListVM().getObservableOfDocListChanged()
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(docModels -> {
                    if (view != null) {
                        view.updateAllDocList(docModels);
                    }
                }));

        if (view != null) {
            view.updateMediaCoursewareList(liveRoom.getDocListVM().getMediaCoursewareList());
        }

        compositeDisposable.add(liveRoom.getDocListVM().getObservableOfMediaCoursewareList()
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(mediaCoursewareModelList -> {
                    if (view != null) {
                        view.updateMediaCoursewareList(liveRoom.getDocListVM().getMediaCoursewareList());
                    }
                }));

        compositeDisposable.add(liveRoom.getDocListVM().getObservableOfHomeworkListChanged()
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(homeworkAllModel -> {
                    if (view != null) {
                        view.updateAllHomework(homeworkAllModel);
                    }
                }));
        compositeDisposable.add(liveRoom.getDocListVM().getObservableOfHomeworkSearchRstListChanged()
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(homeworkAllModel -> {
                    if (view != null) {
                        view.updateHomeworkSearchRst(homeworkAllModel);
                    }
                }));
        compositeDisposable.add(liveRoom.getCloudFileVM().getObservableOfCloudListChanged()
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(lpCloudFileModels -> {
                    if (view != null) {
                        view.updateAllCloudFile(lpCloudFileModels);
                    }
                }));
        compositeDisposable.add(liveRoom.getCloudFileVM().getObservableOfDirRecordChanged()
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(dirRecordModels -> {
                    if (view != null) {
                        view.updateCloudDirRecord(dirRecordModels);
                    }
                }));
        compositeDisposable.add(liveRoom.getDocListVM().getObservableOfHomeworkSupport()
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(support -> {
                    if (support != null && view != null) {
                        view.updateHomeworkSupport(support);
                    }
                }));

        liveRoom.getDocListVM().requestHomeworkAllList("");
        liveRoom.getCloudFileVM().requestCloudFileAll();
        liveRoom.getDocListVM().requestHomeworkSupport();
        if (view != null) {
            view.updateAllDocList(liveRoom.getDocListVM().getDocList());
            view.updateAllHomework(liveRoom.getDocListVM().getHomeworkModelList());
            view.updateAllCloudFile(liveRoom.getCloudFileVM().getCloudFileList());
            view.updateAllowUpdateHomework(liveRoom.getDocListVM().getAllowUploadHomework().isAllow());
        }

        // 是否允许学生上传作业
        compositeDisposable.add(liveRoom.getDocListVM().getObservableOfAllowUploadHomework()
                .observeOn(AndroidSchedulers.mainThread())
                .map(LPAllowUploadHomeworkModel::isAllow)
                .subscribe(isAllow -> {
                    if (view != null) {
                        view.updateAllowUpdateHomework(isAllow);
                    }
                }));
    }

    @Override
    public boolean enableImageShowAsDoc() {
        if (liveRoom == null) {
            return false;
        }
        return liveRoom.getPartnerConfig().enableImageShowAsDoc;
    }

    @Override
    public void unSubscribe() {
        for (Map.Entry<String, Disposable> entry : disposablesOfRequestProgress.entrySet()) {
            LPRxUtils.dispose(entry.getValue());
            if (view != null) {
                view.removeUploadDocument(entry.getKey());
            }
        }
        disposablesOfRequestProgress.clear();
        for (Disposable disposable : disposablesOfUploading.values()) {
            LPRxUtils.dispose(disposable);
        }
        disposablesOfUploading.clear();
        compositeDisposable.clear();
        LPRxUtils.dispose(disposableOfReqImg);
        liveRoom = null;
    }

    @Override
    public void destroy() {
        view = null;
        unSubscribe();
    }

    abstract class CourseManageUploadCallback extends BJProgressCallback {
        LPUploadingDocumentModel model;
        protected LPShortResult<?> shortResult = null;

        public CourseManageUploadCallback(LPUploadingDocumentModel model) {
            this.model = model;
        }

        @Override
        public void onProgress(long progress, long total) {
            if (view == null) {
                return;
            }
            view.uploadProgress(model.getFilePath(), (int) ((double) progress / total) * 100);
        }

        @Override
        public void onFailure(HttpException e) {
            model.setStatus(LPUploadingDocumentModel.STATUS_UPLOAD_FAILED);
            if (view == null) {
                return;
            }
            if (e.getCode() != HttpException.CODE_ERROR_UNKNOWN) {
                view.uploadFailure(model, "未知错误：" + e.getMessage());
            }
        }

        @CallSuper
        @Override
        public void onResponse(BJResponse response) {
            if (view == null || liveRoom == null) {
                continueQueue();
                return;
            }
            try {
                ResponseBody responseBodyCopy = response.getResponse().body(); //.peekBody(Long.MAX_VALUE);
                if (responseBodyCopy == null) {
                    continueQueue();
                    return;
                }
                shortResult = LPJsonUtils.parseString(responseBodyCopy.string(), LPShortResult.class);
                if (shortResult.errNo != 0 || shortResult.data == null) {
                    model.setStatus(LPUploadingDocumentModel.STATUS_UPLOAD_FAILED);
                    view.uploadFailure(model, shortResult.message);
                    shortResult = null;
                    continueQueue();
                }
            } catch (Exception e) {
                model.setStatus(LPUploadingDocumentModel.STATUS_UPLOAD_FAILED);
                view.uploadFailure(model, "未知错误：" + e.getMessage());
                e.printStackTrace();
                continueQueue();
            }
        }

        private void continueQueue() {
            if (model.isImg()) {
                continueUploadImageQueue();
            } else {
                continueUploadQueue();
            }
        }
    }
}
